Vue Object.defineProperty及ProxyVue实现双向数据绑定
function myVue(option) {
let attrVal = node.getAttribute('v-click')
创建Vue实例(new myVue)
}
_this._binding[key].forEach((item) => { // 当number改变时,触发_binding[number] 中的绑定的Watcher类的更新
</script>
}
increment() {
</html>
let attrVal = node.getAttribute('v-bind')
}
if (!_this._binding[attrVal]) _this._binding[attrVal] = []
let attrVal = node.getAttribute('v-model')
node.onclick = _this.$methods[attrVal].bind(_this.$data) // bind是使data的作用域与method函数的作用域保持一致
let attrVal = node.getAttribute('v-click')
<script>
number: 0,
}
methods: {
<div>
// 绑定更新函数,实现对 DOM 元素的更新
<body>
return target[key]; // 获取该对象上key的值
let nodes = Array.prototype.slice.call(el.children) // 将为数组转化为真正的数组
this.attr = attr // 绑定的属性值,本例为"innerHTML","value"
_this._binding[attrVal].push(new Watcher(
node, // 对应的 DOM 节点
// 比如 H3.innerHTML = this.data.number; 当number改变时,会触发这个update函数,保证对应的DOM内容进行了更新
}
}
if (node.hasAttribute('v-bind')) {
this.$el = document.querySelector(options.el) // el是 #app, this.$el是id为app的Element元素
<title>myVue</title>
item.update();
myVue.prototype._init = function (options) { // 传了一个配置对象
<h3 v-bind="number"></h3>
this.$data = options.data // this.$data = {number: 0}
count: 0
incre() {
set: (newVal) => { // 更新 value 值
_this.$data[attrVal] = node.value // 使number 的值与 node的value保持一致,已经实现了双向绑定
this.$data = new Proxy(data, handler);
},
<h3 v-bind="number"></h3>
_complie(el) { // el 为id为app的Element元素,也就是我们的根元素
</script>
</div>
this.$options = options // options 为上面使用时传入的结构体,包括el,data,methods
if (node.children.length && node.children.length > 0) this._complie(node)
this.update()
}
}
}
'innerHTML'
this.data = data // 代理的对象 this.$data 数据: {number: 0, count: 0}
increment() {
}
// 数据劫持:更新数据
function Watcher(el, data, key, attr) {
</div>
// 如果有v-model属性,并且元素是INPUT或者TEXTAREA,我们监听它的input事件
incre() {
1.object.defineproperty方式实现双向数据绑定
this.$options = options // options 为上面使用时传入的结构体,包括el,data,methods
_this._binding[key].map(item => {
return res;
</style>
get(target, key) {
if (node.hasAttribute('v-model') && (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA')) {
}
实现数据层的更新:数据劫持,定义一个 obverse 函数重写data的set和get(myVue.prototype._obsever)
}
<input type="text" v-model="number" />
if (typeof value === 'object') { //如果值还是对象,则遍历处理
data: {
enumerable: true,
#app{
}
constructor (el, data, key, attr) {
number: 0,
})
<script>
if (node.children.length && node.children.length > 0) this._complie(node)
node,
}
_this._compile(node)
let _this = this
<!DOCTYPE html>this.count++
}
this._binding = {}
let _this = this
))
let attrVal = node.getAttribute('v-bind')
})
</div>
attrVal, // v-model 绑定的值
_this._binding[attrVal].push(new Watcher(
Object.defineProperty(_this.$data, key, {
<script>
get(target, key) {
this.$data = options.data // this.$data = {number: 0}
})
return value
};
this.$methods = options.methods // this.$methods = {increment: function(){}}
this.attr = attr // 绑定的属性值,本例为"innerHTML","value"
}
2.Proxy 实现双向数据绑定
myVue.prototype._init = function (options) { // 传了一个配置对象
function Watcher(el, data, key, attr) {
this.$methods = options.methods // this.$methods = {increment: function(){}}
<input type="text" v-model="number" />
class MyVue {
#app{
data: {
node.addEventListener('input', () => {
</form>
this.data = data // this.$data 数据: {number: 0, count: 0}
}
}
this.$options = options // options 为上面使用时传入的结构体,包括el,data,methods
// 将view与model进行绑定,解析指令(v-bind,v-model,v-clickde)等
},
this.$methods = options.methods // this.$methods = {increment: function(){}}
}
let _this = this
#app{
node,
<button type="button" v-click="increment">增加</button>
// 将view与model进行绑定,解析指令(v-bind,v-model,v-clickde)等
// 把代理器返回的对象代理到this.$data,即this.$data是代理后的对象,外部每次对this.$data进行操作时,实际上执行的是这段代码里handler对象上的方法
attrVal, // v-bind 绑定的值
})
attrVal, // v-model 绑定的值
let nodes = Array.prototype.slice.call(el.children) // 将为数组转化为真正的数组
}
this.el[this.attr] = this.data[this.key]
</style>
let _this = this
node.addEventListener('input', () => {
<style>
this._obsever(this.$data)
if (node.hasAttribute('v-bind')) {
},

))
'value',
let attrVal = node.getAttribute('v-bind')
let value = obj[key]
))
<html>
}
</form>
if (node.hasAttribute('v-click')) { // 如果有v-click属性,我们监听它的onclick事件,触发increment事件,即number++

let res = Reflect.set(target, key, newValue); // 将新值分配给属性的函数
myVue.prototype._compile = function (el) { // root 为id为app的Element元素,也就是我们的根元素
})
this.number++
<body>
// 如果有v-model属性,并且元素是INPUT或者TEXTAREA,我们监听它的input事件
attrVal, // v-model 绑定的值
this.count++
nodes.map(node => {
// 定义一个myVue构造函数
el: '#app',
Watcher.prototype.update = function () {
}
<input type="text" v-model="number" />
})
_this._binding[key].map(item => {
update () {
window.onload = () => { // 当文档内容完全加载完成会触发该事件,避免获取不到对象的情况
let attrVal = node.getAttribute('v-model')
<button type="button" v-click="increment">增加</button>
let _this = this
this.$el = document.querySelector(options.el) // el是 #app, this.$el是id为app的Element元素
this._init(option)
text-align: center;
value = newVal
this.$data = options.data // this.$data = {number: 0}
},
let handler = {
window.onload = () => { // 当文档内容完全加载完成会触发该事件,避免获取不到对象的情况
}
this.update()
methods: {
// _binding保存着model与view的映射关系,也就是我们前面定义的Watcher的实例。当model改变时,我们会触发其中的指令类更新,保证view也能实时更新
<button type="button" v-click="increment">增加</button>
new myVue({
}
<title>myVue</title>
this.el = el // 指令对应的DOM元素
_this.$data[attrVal] = node.value // 使number 的值与 node的value保持一致,已经实现了双向绑定
this.$data = new Proxy(data, handler);
this._complie(this.$el)
</form>
let nodes = Array.prototype.slice.call(el.children) // 将为数组转化为真正的数组
if (obj.hasOwnProperty(key)) { // 判断 obj 对象是否包含 key属性
return target[key]; // 获取该对象上key的值
<!DOCTYPE html>}
</body>
</head>
<style>
}
node.onclick = _this.$methods[attrVal].bind(_this.$data) // bind是使data的作用域与method函数的作用域保持一致
new myVue({
</head>
_this.$data,
node.addEventListener('input', () => {
configurable: true,
get: () => { // 获取 value 值
nodes.map(node => {
'value',
});
定义一个Vue的构造函数并初始化这个函数(myVue.prototype._init)
}
<body>
this.el = el // 指令对应的DOM元素
myVue.prototype._complie = function (el) { // el 为id为app的Element元素,也就是我们的根元素
node, // 对应的 DOM 节点
将数据和视图层进行绑定,解析指令v-bind、v-model、v-click(myVue.prototype._compile)
increment() {
_obsever (data) { // 数据劫持:更新数据
this.$el = document.querySelector(options.el) // el是 #app, this.$el是id为app的Element元素
},
this.key = key // 指令绑定的值,本例如"num"
_this.$data,
<!DOCTYPE html>}
}
}
_this._binding[attrVal].push(new Watcher(
item.update() // 调 Watcher 实例的 update 方法更新 DOM
incre() {
this.attr = attr // 绑定的属性值,本例为"innerHTML","value"
constructor(options) { // 接收了一个配置对象
this.el = el // 指令对应的DOM元素
this.count++
_this._binding[key] = [] // 按照前面的数据,_binding = {number: []} 存储 每一个 new Watcher
this._binding = {}
}
'value'
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
item.update();
this._obsever(this.$data)
this.update()
</script>
let handler = {
<html>
// 数据劫持:更新数据
}
this.el[this.attr] = this.data[this.key]
node.onclick = _this.$methods[attrVal].bind(_this.$data) // bind是使data的作用域与method函数的作用域保持一致
}
}
this.key = key // 指令绑定的值,本例如"num"
};
}
if (node.hasAttribute('v-model') && (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA')) {
<div>
<head>
</body>
}
// 比如 H3.innerHTML = this.data.number; 当number改变时,会触发这个update函数,保证对应的DOM内容进行了更新
attrVal, // v-bind 绑定的值
))
node, // 对应的 DOM 节点
})
))
_this.$data[attrVal] = node.value // 使number 的值与 node的value保持一致,已经实现了双向绑定
},
let attrVal = node.getAttribute('v-model')
})
methods: {
this.number++
},
el: '#app',
</html>
myVue.prototype._obsever = function (data) {
}
</style>
if (value !== newVal) {
nodes.map(node => {
双向数据绑定无非就是,视图 => 数据,数据 => 视图的更新过程
this._compile(this.$el)
))
}
实现视图层的更新:订阅者模式,定义个 Watcher 函数实现对DOM的更新(Watcher)
<style>
_this.$data,
_this.$data,
<h3 v-bind="number"></h3>
_this.$data,
})
this.number++
set(target, key, newValue) {
<html>
_this.$data,
// 把代理器返回的对象代理到this.$data,即this.$data是代理后的对象,外部每次对this.$data进行操作时,实际上执行的是这段代码里handler对象上的方法
// 定义一个myVue构造函数
'innerHTML',
data: {
text-align: center;
myVue.prototype._obsever = function (obj) {
this._obsever(this.$data)
let _this = this
}
text-align: center;
window.onload = () => { // 当文档内容完全加载完成会触发该事件,避免获取不到对象的情况
_this._obsever(value)
</head>
}
return res;
<form>
this._binding = {}
_this._binding[attrVal].push(new Watcher(
count: 0
if (node.children.length && node.children.length > 0) { // 对所有元素进行遍历,并进行处理
if (node.hasAttribute('v-model') && (node.tagName === 'INPUT' || node.tagName === 'TEXTAREA')) {
}
})
if (node.hasAttribute('v-click')) { // 如果有v-click属性,我们监听它的onclick事件,触发increment事件,即number++
number: 0,
},
})
Object.keys(obj).forEach((key) => { // 遍历obj对象
<form>
let attrVal = node.getAttribute('v-click')
if (!_this._binding[attrVal]) _this._binding[attrVal] = []
},
</body>
if (node.hasAttribute('v-click')) { // 如果有v-click属性,我们监听它的onclick事件,触发increment事件,即number++
this.el[this.attr] = this.data[this.key]
<title>myVue</title>
3.将上面代码改成class的写法
new MyVue({
});
this.data = data // 代理的对象 this.$data 数据: {number: 0, count: 0}
<div>
node,
this.key = key // 指令绑定的值,本例如"number"
// 订阅者模式: 绑定更新函数,实现对 DOM 元素的更新
}
attrVal, // v-bind 绑定的值
function myVue(option) {
let res = Reflect.set(target, key, newValue); // 将新值分配给属性的函数
以下的方案中的实现思路:
if (node.hasAttribute('v-bind')) {
<form>
el: '#app',
count: 0
Watcher.prototype.update = function () {
}
class Watcher {
this._init(option)
</html>
}
<head>
this._complie(this.$el)
}
set(target, key, newValue) {
}
}
// 如果有v-model属性,并且元素是INPUT或者TEXTAREA,我们监听它的input事件
if (!_this._binding[attrVal]) _this._binding[attrVal] = []
console.log(_this._binding)
'innerHTML',
_this._binding[attrVal].push(new Watcher(
})
if (!_this._binding[attrVal]) _this._binding[attrVal] = []
<head>
_this._binding[attrVal].push(new Watcher(
相关热词:
本站内容来源于网络,如有侵权请与我们联系,我们会及时删除,我们深感抱歉!
注:本站所有信息仅供用于网络技术学习参考,学习中请遵循相关法律法规!
本文地址: https://v30.fanwenzhu.com/jz/wp/4752.shtml
相关文章
热门TAG
win10 ecshop 主机 阿里云 解决 配置 C# C++ 解析 SQL语句 命令 Go语言 方法 CSS3 HTML5 CSS win7 MSSQL 服务器配置 IIS7.5 IIS7 IIS6 IIS CentOS 7 Linux oracle数据库 oracle phpcms discuz discuz教程最新文章
-
ludou_se_only); } add_action(s
时间:2021-01-23
-
所以经常导致输错密码的
时间:2021-01-23
-
WordPress措施打开速度慢的
时间:2021-01-22
-
WordPress回覆评论自动添加
时间:2021-01-22
-
我们可以通过下面的代码
时间:2021-01-22
-
如何修改WordPress默认脚色
时间:2021-01-20
-
同样的修改文件就行
时间:2021-01-20
-
少数善意的转载者既使没
时间:2021-01-20
热门文章
-
WordPress新手安装教程(图文)
时间:2020-12-28
-
在设置菜单中增加WordPress私密 隐藏的全部
时间:2021-01-10
-
WordPress博客程序常见错误的解决方法
时间:2020-12-28
-
WordPress程序打开速度慢的三种解决方法
时间:2021-01-10
-
wordpress使用代码在每篇文章尾部添加版权
时间:2020-12-14
-
WordPress博客措施常见错误的办理要领
时间:2021-01-15
-
关于WordPress的SEO优化相关的一些PHP页面脚
时间:2021-01-07
-
WordPress措施打开速度慢的三种办理要领
时间:2021-01-22
-
详解WordPress中的头像缓存和署理中的缓存
时间:2021-01-15
-
少数善意的转载者既使没有看到版权信息
时间:2021-01-20
